package com.walkline.screen;

import java.io.IOException;

import javax.microedition.content.ContentHandler;
import javax.microedition.content.ContentHandlerException;
import javax.microedition.content.Invocation;
import javax.microedition.content.Registry;
import javax.microedition.io.file.FileSystemListener;

import localization.RedFlowerResource;
import net.rim.blackberry.api.browser.Browser;
import net.rim.blackberry.api.browser.BrowserSession;
import net.rim.device.api.i18n.ResourceBundle;
import net.rim.device.api.system.Application;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Branding;
import net.rim.device.api.system.Characters;
import net.rim.device.api.system.Clipboard;
import net.rim.device.api.system.DeviceInfo;
import net.rim.device.api.system.Display;
import net.rim.device.api.system.GPRSInfo;
import net.rim.device.api.system.Memory;
import net.rim.device.api.system.MemoryStats;
import net.rim.device.api.system.RadioInfo;
import net.rim.device.api.system.RadioStatusListener;
import net.rim.device.api.system.SystemListener;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.FontFamily;
import net.rim.device.api.ui.FontManager;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.Ui;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
import net.rim.device.api.ui.menu.DefaultContextMenuProvider;
import net.rim.device.api.ui.menu.SubMenu;
import net.rim.device.api.util.StringProvider;

import com.walkline.app.RedFlowerAppConfig;
import com.walkline.ui.ForegroundManager;
import com.walkline.ui.ListStyleButtonField;
import com.walkline.ui.ListStyleButtonSet;
import com.walkline.ui.VerticalButtonFieldSet;
import com.walkline.util.Functions;
import com.walkline.util.WirelessStatus;

public class RedFlowerScreen extends MainScreen implements FileSystemListener, SystemListener, RadioStatusListener, RedFlowerResource
{
	private static ResourceBundle _resources = ResourceBundle.getBundle(BUNDLE_ID, BUNDLE_NAME);

	private static boolean _useLargeIcon = Display.getWidth() >= 640;
	private static Bitmap _bitmapMoreInfo = _useLargeIcon ? Bitmap.getBitmapResource("moreInfo_large.png") : Bitmap.getBitmapResource("moreInfo_small.png");
	private static Bitmap _bitmapAppTitle = _useLargeIcon ? Bitmap.getBitmapResource("titleIcon_large.png") : Bitmap.getBitmapResource("titleIcon_small.png");

	private ForegroundManager _foreground;
	private RedFlowerAppConfig _appConfig;

	private ListStyleButtonSet informationSet;
	private ListStyleButtonSet storageSet;
	private ListStyleButtonSet vendorSet;

	private ListStyleButtonField imei;
	private ListStyleButtonField battery;
	private ListStyleButtonField signal;

    public RedFlowerScreen(RedFlowerAppConfig appConfig)
    {            
    	super(NO_VERTICAL_SCROLL | USE_ALL_HEIGHT | NO_SYSTEM_MENU_ITEMS);

    	//setContextMenuProvider(new DefaultContextMenuProvider());
    	//setDefaultClose(false);

    	_appConfig = appConfig;

		try {
			FontFamily family = FontFamily.forName("BBGlobal Sans");
			Font appFont = family.getFont(Font.PLAIN, 8, Ui.UNITS_pt);
			FontManager.getInstance().setApplicationFont(appFont);
		} catch (ClassNotFoundException e) {}

		BitmapField bmpTitleField = new BitmapField(_bitmapAppTitle);
		bmpTitleField.setSpace(5, 5);
		LabelField labelTitleField = new LabelField(RedFlowerAppConfig.APP_TITLE, LabelField.ELLIPSIS);
		labelTitleField.setFont(RedFlowerAppConfig.FONT_MAIN_TITLE);

		HorizontalFieldManager hfm = new HorizontalFieldManager(USE_ALL_WIDTH);
		VerticalFieldManager vfm = new VerticalFieldManager(FIELD_VCENTER);
		vfm.add(labelTitleField);
		hfm.add(bmpTitleField);
		hfm.add(vfm);
		hfm.setBackground(RedFlowerAppConfig.bgColor_Gradient);
		setTitle(hfm);

    	informationSet=new ListStyleButtonSet();
    	ListStyleButtonField link = new ListStyleButtonField(getResString(DEVICE_INFORMATION_TITLE), LabelField.HCENTER | LabelField.ELLIPSIS | USE_ALL_WIDTH); 
    	link.setChangeListener(new FieldChangeListener() {
			public void fieldChanged(Field field, int context) 
			{
				if(informationSet.getCookie().equals("show"))
				{
					hideUI(informationSet);					
				} else {
					initUIDeviceInformation();
				}
			}
		});
    	informationSet.add(link);
   		initUIDeviceInformation();

    	storageSet=new ListStyleButtonSet();
    	ListStyleButtonField link1=new ListStyleButtonField(getResString(STORAGE_INFORMATION_TITLE), LabelField.HCENTER | LabelField.ELLIPSIS | USE_ALL_WIDTH);
    	//link1.setFont(Font.getDefault().derive(Font.PLAIN, Font.getDefault().getHeight(Ui.UNITS_pt)+1, Ui.UNITS_pt));
    	link1.setChangeListener(new FieldChangeListener() {
			public void fieldChanged(Field field, int context)
			{
				if(storageSet.getCookie().equals("show"))
				{
					hideUI(storageSet);
				} else {
					initUIStorageInformation();
				}
			}
		});
    	storageSet.add(link1);
   		initUIStorageInformation();
    	
    	vendorSet=new ListStyleButtonSet();
    	ListStyleButtonField link2=new ListStyleButtonField(getResString(VENDOR_INFORMATION_TITLE), LabelField.HCENTER | LabelField.ELLIPSIS | USE_ALL_WIDTH);
    	//link2.setFont(Font.getDefault().derive(Font.PLAIN, Font.getDefault().getHeight(Ui.UNITS_pt)+1, Ui.UNITS_pt));
    	link2.setChangeListener(new FieldChangeListener() {
			public void fieldChanged(Field field, int context)
			{
				if(vendorSet.getCookie().equals("show"))
				{
					hideUI(vendorSet);
				} else {
					initUIVendorInformation();
				}
			}
		});
    	vendorSet.add(link2);
   		initUIVendorInformation();

   		_foreground=new ForegroundManager(0);
    	_foreground.add(informationSet);
    	_foreground.add(storageSet);
    	_foreground.add(vendorSet);
    	add(_foreground);

       	Application.getApplication().addFileSystemListener(this);
    	Application.getApplication().addSystemListener(this);
    	Application.getApplication().addRadioListener(this);
    }

    private void initUIDeviceInformation()
    {
    	ListStyleButtonField link=new ListStyleButtonField(getResString(DEVICE_INFORMATION_DEVICE_MODEL) , DeviceInfo.getDeviceName(), 0);
    	informationSet.add(link);

    	//ListStyleButtonField pin=new ListStyleButtonField(getResString(DEVICE_INFORMATION_PIN) , Integer.toHexString(DeviceInfo.getDeviceId()).toUpperCase(), 0);
    	ListStyleButtonField pin=new ListStyleButtonField(getResString(DEVICE_INFORMATION_PIN) , Integer.toHexString(DeviceInfo.getDeviceId()).toUpperCase(), _bitmapMoreInfo);
    	pin.setChangeListener(new FieldChangeListener() {
			public void fieldChanged(Field field, int context)
			{
				UiApplication.getUiApplication().pushScreen(new QRCodeScreen());				
			}
		});
    	informationSet.add(pin);
    	
    	imei=new ListStyleButtonField(getResString(DEVICE_INFORMATION_IMEI), GPRSInfo.imeiToString(GPRSInfo.getIMEI()), _bitmapMoreInfo);
    	imei.setChangeListener(new FieldChangeListener() {
			public void fieldChanged(Field field, int context) {
				Clipboard cb=Clipboard.getClipboard();
				
				cb.put(new String(GPRSInfo.imeiToString(GPRSInfo.getIMEI())));
				Dialog.alert(getResString(MESSAGE_INFO_IMEI_COPIED));
			}
		});
    	informationSet.add(imei);
    	
    	link=new ListStyleButtonField(getResString(DEVICE_INFORMATION_SOFTWARE_VERSION) , DeviceInfo.getSoftwareVersion(), 0);
    	informationSet.add(link);
    	
    	link=new ListStyleButtonField(getResString(DEVICE_INFORMATION_PLATFORM_VERSION) , DeviceInfo.getPlatformVersion(), 0);
    	informationSet.add(link);
    	
    	String wirelessStatus=new WirelessStatus().getWirelessDescriptor();
    	if(wirelessStatus.equals(""))
    	{
    		signal=new ListStyleButtonField(getResString(DEVICE_INFORMATION_SIGNAL), RadioInfo.getSignalLevel() + " dBm", 0);
    	} else
    	{
    		signal=new ListStyleButtonField(getResString(DEVICE_INFORMATION_SIGNAL),RadioInfo.getCurrentNetworkName() + " " + wirelessStatus + " (" + RadioInfo.getSignalLevel() + " dBm)", 0);
		}
    	informationSet.add(signal);
    	
    	battery=new ListStyleButtonField(getResString(DEVICE_INFORMATION_BATTERY_LEVEL) ,  DeviceInfo.getBatteryLevel() + "%", _bitmapMoreInfo);
    	battery.setChangeListener(new FieldChangeListener() {
			public void fieldChanged(Field field, int context) {
				UiApplication.getUiApplication().pushScreen(new BatteryInfoScreen());
			}
		});
    	informationSet.add(battery);
    	informationSet.setCookie("show");	
    }

    private void initUIStorageInformation()
    {
    	MemoryStats memRamStats= Memory.getRAMStats();
    	ListStyleButtonField link=new ListStyleButtonField(getResString(STORAGE_INFORMATION_RAM_USAGE) , Functions.formatSize(memRamStats.getAllocated(), 1) + " / " + Functions.formatSize(memRamStats.getFree() + memRamStats.getAllocated(), 1),0); //sizeformat(Memory.getFlashStats().getFree(),false)+ sizeformat(Memory.getFlashTotal(),true), 0);
    	storageSet.add(link);
 
    	link=new ListStyleButtonField(getResString(STORAGE_INFORMATION_FLASH_STORAGE), Functions.formatSize(DeviceInfo.getTotalFlashSizeEx(), 1) + " (" + Functions.formatSize(Memory.getFlashFree(), 1) + " free)" , 0);
    	storageSet.add(link);

    	link=new ListStyleButtonField(getResString(STORAGE_INFORMATION_BUILTIN_STORAGE), Functions.getStorageInfo("store/"), 0);
    	storageSet.add(link);
    	
    	link=new ListStyleButtonField(getResString(STORAGE_INFORMATION_MEDIA_CARD_STORAGE), Functions.getStorageInfo("SDCard/"), 0);
    	storageSet.add(link);	
    	storageSet.setCookie("show");
    }

    private void initUIVendorInformation()
    {
    	int vendorID=Branding.getVendorId();
    	ListStyleButtonField link=new ListStyleButtonField(getResString(VENDOR_INFORMATION_VENDOR_ID) , String.valueOf(vendorID),0);
    	vendorSet.add(link);

    	int vIndex=Functions.findInArray(RedFlowerAppConfig.VendorID, vendorID);
    	final String vendorName;
    	
    	if(vIndex!=-1){
    		vendorName=RedFlowerAppConfig.VendorName[vIndex];    		
    	}else{
    		vendorName=getResString(VENDOR_INFORMATION_UNKNOWN);
    	}
    	
    	ListStyleButtonField vendorNameField=new ListStyleButtonField("", "----" + vendorName, ButtonField.ELLIPSIS);
    	vendorNameField.setChangeListener(new FieldChangeListener() {
			public void fieldChanged(Field field, int context) {
				VendorNameScreen vns=new VendorNameScreen(vendorName);
				UiApplication.getUiApplication().pushScreen(vns);
			}
		});
    	vendorSet.add(vendorNameField);
    	
    	VerticalButtonFieldSet viewVendorSet=new VerticalButtonFieldSet(USE_ALL_WIDTH);
    	ButtonField btnViewVendors=new ButtonField(getResString(VENDOR_INFORMATION_VIEW_ALL_VENDORS), ButtonField.NEVER_DIRTY | ButtonField.CONSUME_CLICK);
    	btnViewVendors.setChangeListener(new FieldChangeListener() {
			public void fieldChanged(Field field, int context)
			{
		        showAllVendors();
			}
		});
    	viewVendorSet.setMargin(0,0,0,0);
    	viewVendorSet.setPadding(2, 5, 2, 5);
    	viewVendorSet.add(btnViewVendors);
    	vendorSet.add(viewVendorSet);
    	vendorSet.setCookie("show");	
    }

    private void updateSignalLevel()
    {
    	String wirelessStatus=new WirelessStatus().getWirelessDescriptor();
    	if(wirelessStatus.equals(""))
    	{
    		signal.setRightText(RadioInfo.getSignalLevel() + " dBm");
    	} else {
    		signal.setRightText(RadioInfo.getCurrentNetworkName() + " " + wirelessStatus + " (" + RadioInfo.getSignalLevel() + " dBm)");
		}
    }

    private void updateBatteryLevel()
    {
    	battery.setRightText(DeviceInfo.getBatteryLevel() + "%");
    }

    private void hideUI(ListStyleButtonSet UIContainer)
    {
    	UIContainer.deleteRange(1, UIContainer.getFieldCount()-1);
    	UIContainer.setCookie("hide");
    }

    private MenuItem menuFlashlight = new MenuItem(new StringProvider(getResString(MENU_FLASHLIGHT)), 100, 10)
    {
    	public void run() {showFlashlight();}
    };

    private MenuItem menuShowIMSI = new MenuItem(new StringProvider(getResString(MENU_SHOW_IMSI)), 100, 20)
    {
    	public void run() {Functions.showIMSI();}
    };

    private MenuItem menuViewAllVendors = new MenuItem(new StringProvider(getResString(MENU_VIEW_ALL_VENDORS)), 100, 30)
    {
    	public void run() {showAllVendors();}
    };

    private MenuItem menuSettings = new MenuItem(new StringProvider(getResString(MENU_SETTINGS)), 100, 50)
    {
    	public void run() {showSettings();}
    };

    private MenuItem menuAbout = new MenuItem(new StringProvider(getResString(MENU_ABOUT)), 100, 60)
    {
    	public void run() {showAbout();}
    };

    private MenuItem menuExit = new MenuItem(new StringProvider(getResString(MENU_EXIT)), 100, 70)
    {
    	public void run() {System.exit(0);}
    };

    private MenuItem menuWriteAReview=new MenuItem(new StringProvider(getResString(MENU_BBW_WRITE_A_REVIEW)), 200, 10)
    {
    	public void run()
    	{
    		try
            {
                openAppWorld("25682903");
            } catch(final Exception e)
            {
                UiApplication.getUiApplication().invokeLater(new Runnable()
                {
                    public void run()
                    {
                    	if(e instanceof ContentHandlerException)
                    	{
                    		Dialog.alert("BlackBerry World is not installed!");
                    	} else {
                    		Dialog.alert( "Problems opening App World: " + e.getMessage() );
                    	}
                    }
                });
            }
    	}
    };

    private MenuItem menuBrowseOtherApps=new MenuItem(new StringProvider(getResString(MENU_BBW_BROWSE_OTHER_APPS)), 200, 20)
    {
    	public void run()
    	{
    		BrowserSession browser=Browser.getDefaultSession();
    		browser.displayPage("http://appworld.blackberry.com/webstore/vendor/69061");
    	}
    };

	protected void makeMenu(Menu menu,int instance)
	{
		//super.makeMenu(menu, instance);

    	SubMenu menuBBWorld=new SubMenu(null, getResString(MENU_BBW), 100, 40);
    	menuBBWorld.add(menuWriteAReview);
    	menuBBWorld.addSeparator();
    	menuBBWorld.add(menuBrowseOtherApps);

    	menu.add(menuFlashlight);
    	menu.add(menuShowIMSI);
    	menu.add(menuViewAllVendors);

    	//if (instance == Menu.INSTANCE_DEFAULT)
    	//{
        	menu.addSeparator();
        	menu.add(menuBBWorld);
        	menu.addSeparator();
        	menu.add(menuSettings);
        	menu.addSeparator();
        	menu.add(menuAbout);
        	menu.addSeparator();
        	menu.add(menuExit);
    	//}
    }

	//public boolean onClose()
	//{
	//	UiApplication.getUiApplication().popScreen(this);

	//	return true;
	//}

    private void showFlashlight() {UiApplication.getUiApplication().pushScreen(new FlashLightScreen());}

    private void showAllVendors() {UiApplication.getUiApplication().pushScreen(new VendorsSearchScreen());}

    private void showAbout() {UiApplication.getUiApplication().pushScreen(new AboutScreen());}

    private void showSettings() {UiApplication.getUiApplication().pushScreen(new SettingsScreen(_appConfig));}

	private void openAppWorld(String myContentId) throws IllegalArgumentException, ContentHandlerException, SecurityException, IOException 
    {
		Registry registry = Registry.getRegistry(RedFlowerScreen.class.getName());
		Invocation invocation = new Invocation( null, null, "net.rim.bb.appworld.Content", true, ContentHandler.ACTION_OPEN );

        invocation.setArgs(new String[] {myContentId});

        boolean mustExit = registry.invoke(invocation);
        if(mustExit) {UiApplication.getUiApplication().popScreen(this);}
    }

    private String getResString(int key) {return _resources.getString(key);}

	protected boolean keyChar(char character, int status, int time)
	{
		switch (character)
		{
			case Characters.LATIN_CAPITAL_LETTER_F:
			case Characters.LATIN_SMALL_LETTER_F:
				showFlashlight();
				return true;
			case Characters.LATIN_CAPITAL_LETTER_A:
			case Characters.LATIN_SMALL_LETTER_A:
				showAbout();
				return true;
			case Characters.LATIN_CAPITAL_LETTER_S:
			case Characters.LATIN_SMALL_LETTER_S:
				Functions.showIMSI();
				return true;
			case Characters.LATIN_CAPITAL_LETTER_V:
			case Characters.LATIN_SMALL_LETTER_V:
				showAllVendors();
				return true;
			case Characters.LATIN_CAPITAL_LETTER_X:
			case Characters.LATIN_SMALL_LETTER_X:
				System.exit(0);
				return true;
		}

		return super.keyChar(character, status, time);
	}

	public void rootChanged(int state, String rootName)
	{
		hideUI(storageSet);
		initUIStorageInformation();
	}

	public void batteryGood() {}
	public void batteryLow() {}
	public void powerOff() {}
	public void powerUp() {}
	public void batteryStatusChange(int status) {updateBatteryLevel();}

	public void baseStationChange() {updateSignalLevel();}
	public void networkScanComplete(boolean success) {updateSignalLevel();}
	public void networkServiceChange(int networkId, int service) {updateSignalLevel();}
	public void networkStarted(int networkId, int service) {updateSignalLevel();}
	public void networkStateChange(int state) {updateSignalLevel();}
	public void pdpStateChange(int apn, int state, int cause) {updateSignalLevel();}
	public void radioTurnedOff() {updateSignalLevel();}
	public void signalLevel(int level) {updateSignalLevel();}
}